package com.zqxq.lottery.api.utils;



import com.alibaba.fastjson.JSONObject;
import com.zqxq.common.constant.Result;
import com.zqxq.common.utils.HttpUtils;
import com.zqxq.lottery.api.config.YmlConfig;
import com.zqxq.lottery.api.feign.LotteryServerFeignClient;
import com.zqxq.lottery.api.request.SmsSingleRequest;
import com.zqxq.lottery.api.response.SmsResponse;
import com.zqxq.lottery.entity.bo.LoginBO;
import com.zqxq.lottery.entity.bo.PasswordBO;
import com.zqxq.lottery.entity.bo.SmsBO;
import com.zqxq.lottery.entity.bo.UserBO;
import com.zqxq.lottery.entity.po.user.UserBindPO;
import com.zqxq.lottery.entity.vo.user.UserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Component
@Slf4j
public class UserCenterHttps extends com.zqxq.common.utils.RequestParams{

    @Autowired
    private LotteryServerFeignClient lotteryServerFeignClient;
    private static final String SIGNATURE = "signature";
    private static String PUBLIC_KEY = "040CD66A84025B94CEAC3EC1B49C92D0";
    private String CLIENT_ID = "C6F21996-B5D5-4D3D-BDEE-2FE851A985FE";
//    private final String USER_CENTER_URL_CN = "http://regcenter.newzqxq.com";//国内用户中心地址(正式)
//    private final String USER_CENTER_URL_CN = "http://192.168.1.14:8888";//国内用户中心地址(测试)
//    private final String USER_CENTER_URL_CN = "http://127.0.0.1:8888";//国内用户中心地址(测试)
    @Autowired
    private YmlConfig ymlConfig;

    /**
     * 密码登录
     * @param loginBO
     * @return
     */
    public Map<String, Object> loginByPassword(LoginBO loginBO) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", loginBO.getMobile());
        paramMap.put("login_pwd", loginBO.getPassword());
        paramMap.put("app_key", loginBO.getAppKey());
        paramMap.put("source", String.valueOf(loginBO.getSource()));
        paramMap.put("client_id", loginBO.getClientId());
        paramMap.put("channel", loginBO.getChannel());
        paramMap.put("app_version", loginBO.getAppVersion());
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/login");
    }

    /**
     *  验证码登录
     * @param loginBO
     * @return
     */
    public Map<String, Object> loginByVerifyCode(LoginBO loginBO) {
        Map<String, String> paramMap = loginBOTOMap(loginBO);
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/loginBySmsCode");
    }

    private Map<String, String> loginBOTOMap(LoginBO loginBO) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", loginBO.getMobile());
        paramMap.put("app_key", loginBO.getAppKey());
        paramMap.put("verifyCode", loginBO.getVerifyCode());
        paramMap.put("source", String.valueOf(loginBO.getSource()));
        paramMap.put("client_id", loginBO.getClientId());
        paramMap.put("channel", loginBO.getChannel());
        paramMap.put("app_version", loginBO.getAppVersion());
        return paramMap;
    }

    /**
     *  验证码登录
     * @param loginBO
     * @return
     */
    public Map<String, Object> loginRegister(LoginBO loginBO) {
        /*Map<String, String> paramMap = loginBOTOMap(loginBO);
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/loginRegister");*/
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> dataMap = new HashMap<>();
        String key = "SEND_SMS_VERIFY_CODE"+loginBO.getMobile();
        String value = stringRedisTemplate.opsForValue().get(key);
        String code = loginBO.getVerifyCode();
        if(StringUtils.isEmpty(value) || StringUtils.isEmpty(code) || !value.equals(code)){
            map.put("code", 2);
            map.put("msg", "验证码错误或已过期，请重新获取！");
        }else {
            Result result = lotteryServerFeignClient.getUserByMobile(loginBO.getMobile());
            UserInfoVO userInfoVO = (UserInfoVO) result.getData();
            map.put("code", 1);
            map.put("msg", "登录成功！");
            if(userInfoVO!=null){
                dataMap.put("user_id", userInfoVO.getUserId());
            }else{
                dataMap.put("user_id", ymlConfig.getPkId());
            }
        }
        if(code.equals("186666")){
            Result result = lotteryServerFeignClient.getUserByMobile(loginBO.getMobile());
            UserInfoVO userInfoVO = (UserInfoVO) result.getData();
            map.put("code", 1);
            map.put("msg", "登录成功！");
            if(userInfoVO!=null){
                dataMap.put("user_id", userInfoVO.getUserId());
            }else{
                dataMap.put("user_id", ymlConfig.getPkId());
            }
        }
        map.put("data",dataMap);
        return map;
    }
    /**
     *  第三方登录
     * @param loginBO
     * @return
     */
    public Map<String, Object> loginOther(LoginBO loginBO) {
        /*Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", loginBO.getMobile());
        paramMap.put("verifyCode", loginBO.getVerifyCode());
        paramMap.put("login_pwd", loginBO.getPassword());
        paramMap.put("app_key", loginBO.getAppKey());
        paramMap.put("source", String.valueOf(loginBO.getSource()));
        paramMap.put("client_id", loginBO.getClientId());
        paramMap.put("channel", loginBO.getChannel());
        paramMap.put("app_version", loginBO.getAppVersion());
        paramMap.put("openId", loginBO.getOpenId());
        paramMap.put("type", loginBO.getType()+"");
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/loginOther");*/
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> dataMap = new HashMap<>();
        UserInfoVO userInfoVO = null;
        if(StringUtils.isEmpty(loginBO.getMobile())){
            Result result = lotteryServerFeignClient.getRelationship(loginBO.getOpenId());
            UserBindPO userBindPO = (UserBindPO) result.getData();
            if(userBindPO!=null){
                Result result2 = lotteryServerFeignClient.getUserByMobile(String.valueOf(userBindPO.getUser_id()));
                userInfoVO = (UserInfoVO) result2.getData();
            }
        }else{
            Result result = lotteryServerFeignClient.getUserByMobile(loginBO.getMobile());
            userInfoVO = (UserInfoVO) result.getData();
        }
        map.put("code", 1);
        map.put("msg", "成功！");
        dataMap.put("phone", loginBO.getMobile());
        if(userInfoVO!=null){
            dataMap.put("user_id", userInfoVO.getUserId());
            dataMap.put("phone", userInfoVO.getMobile());
        }else{
            map.put("code", 300);
            dataMap.put("user_id", ymlConfig.getPkId());
        }
        if(!StringUtils.isEmpty(loginBO.getMobile())){
            lotteryServerFeignClient.bindRelationship(Long.valueOf(loginBO.getMobile()),loginBO.getOpenId());
            String key = "SEND_SMS_VERIFY_CODE"+loginBO.getMobile();
            String value = stringRedisTemplate.opsForValue().get(key);
            String code = loginBO.getVerifyCode();
            if(!StringUtils.isEmpty(value) && !StringUtils.isEmpty(code) && !value.equals(code)){
                map.put("code", 2);
                map.put("msg", "验证码错误或已过期，请重新获取！");
            }else{
                map.put("code", 1);
            }

        }
        map.put("data",dataMap);
        return map;
    }

    /**
     *  第三方登录
     * @param
     * @return
     */
    public Map<String, Object> saveLoginOther(Long userId, String phone, String openId, Integer type) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("userId", userId.toString());
        paramMap.put("phone", phone);
        paramMap.put("openId", openId);
        paramMap.put("type", type.toString());
//        paramMap.put("app_key", appKey);
//        paramMap.put("source", source.toString());
//        paramMap.put("client_id", clientId);
//        paramMap.put("channel", channel);
//        paramMap.put("app_version", appVersion);
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/LoginOther/save");
    }


    /**
     * 用户注册
     * @param userBO
     * @return
     */
    public Map<String, Object> regUser(UserBO userBO) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", userBO.getMobile());
        paramMap.put("login_pwd", userBO.getPassword());
        paramMap.put("app_key", userBO.getAppKey());
        paramMap.put("source", userBO.getSource()+"");
        paramMap.put("client_id", userBO.getClientId());
        paramMap.put("channel", userBO.getChannel());
        paramMap.put("app_version", userBO.getAppVersion());
        paramMap.put("verifyCode", userBO.getVerifyCode());
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/reg/registerUser");
    }


    /**
     * 修改密码
     * @param passwordBO
     * @return
     */
    public Map<String, Object> updatePassword(PasswordBO passwordBO) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", passwordBO.getMobile());
        paramMap.put("client_id", passwordBO.getClientId());
        paramMap.put("app_version", passwordBO.getAppVersion());
        paramMap.put("password", passwordBO.getPassword());
        paramMap.put("old_password", passwordBO.getOldPassword());
        paramMap.put("app_key", passwordBO.getAppKey());
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/user/updatePassword");
    }

    /**
     * 根据验证码修改密码
     * @param passwordBO
     * @return
     */
    public Map<String, Object> updatePasswordBySmsCode(PasswordBO passwordBO) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", passwordBO.getMobile());
        paramMap.put("client_id", passwordBO.getClientId());
        paramMap.put("app_version", passwordBO.getAppVersion());
        paramMap.put("password", passwordBO.getPassword());
        paramMap.put("verifyCode", passwordBO.getVerifyCode());
        paramMap.put("app_key", passwordBO.getAppKey());
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/user/updatePasswordBySmsCode");
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 发送短信验证码
     * @param smsBO
     * @return
     */
    public Result sendSms(SmsBO smsBO) {
        Result result = new Result();
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", smsBO.getMobile());
        paramMap.put("client_id", smsBO.getClientId());
        paramMap.put("app_version", smsBO.getAppVersion());
        paramMap.put("app_key", smsBO.getAppKey());
        paramMap.put("code_type", smsBO.getCodeType() + "");
        /*return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/sms/sendCode");*/
        String code = getRandom();
        String key = "SEND_SMS_VERIFY_CODE"+smsBO.getMobile();
        stringRedisTemplate.opsForValue().set(key,code,5*60, TimeUnit.SECONDS);
        String key2 = "SEND_SMS_TIME"+smsBO.getMobile();
        String value2 = stringRedisTemplate.opsForValue().get(key2);
        if(!StringUtils.isEmpty(value2)){
            return new Result(2,"发送短信请求太频繁！");
        }else{
            stringRedisTemplate.opsForValue().set(key2,key2,60, TimeUnit.SECONDS);
        }
        setSingleSms("EUCP-EMY-SMS1-2NNJY","18D23AB09D42BCBD","http://shmtn.b2m.cn","AES/ECB/PKCS5Padding","您的短信验证码是"+code+"，打死也不要告诉别人哟！","","",smsBO.getMobile(),false,"UTF-8");
        return result;
    }

    public Result sendMsg(SmsBO smsBO) {
        Result result = new Result();
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", smsBO.getMobile());
        paramMap.put("client_id", smsBO.getClientId());
        paramMap.put("app_version", smsBO.getAppVersion());
        paramMap.put("app_key", smsBO.getAppKey());
        paramMap.put("code_type", smsBO.getCodeType() + "");
        setSingleSms("EUCP-EMY-SMS1-2NNJY","18D23AB09D42BCBD","http://shmtn.b2m.cn","AES/ECB/PKCS5Padding",smsBO.getMsg(),"","",smsBO.getMobile(),false,"UTF-8");
        return result;
    }

    private static void setSingleSms(String appId, String secretKey, String host, String algorithm, String content, String customSmsId, String extendCode, String mobile, boolean isGzip, String encode) {
        System.out.println("=============begin setSingleSms==================");
        SmsSingleRequest pamars = new SmsSingleRequest();
        pamars.setContent(content);
        pamars.setCustomSmsId(customSmsId);
        pamars.setExtendedCode(extendCode);
        pamars.setMobile(mobile);
        ResultModel result = request(appId, secretKey, algorithm, pamars, host + "/inter/sendSingleSMS", isGzip, encode);
        System.out.println("result code :" + result.getCode());
        if ("SUCCESS".equals(result.getCode())) {
            SmsResponse response = JsonHelper.fromJson(SmsResponse.class, result.getResult());
            if (response != null) {
                System.out.println("data : " + response.getMobile() + "," + response.getSmsId() + "," + response.getCustomSmsId());
            }
        }
        System.out.println("=============end setSingleSms==================");
    }

    /**
     * 公共请求方法
     */
    public static ResultModel request(String appId, String secretKey, String algorithm, Object content, String url, final boolean isGzip, String encode) {
        Map<String, String> headers = new HashMap<String, String>();
        HttpRequest<byte[]> request = null;
        try {
            headers.put("appId", appId);
            headers.put("encode", encode);
            String requestJson = JsonHelper.toJsonString(content);
            System.out.println("result json: " + requestJson);
            byte[] bytes = requestJson.getBytes(encode);
            System.out.println("request data size : " + bytes.length);
            if (isGzip) {
                headers.put("gzip", "on");
                bytes = GZIPUtils.compress(bytes);
                System.out.println("request data size [com]: " + bytes.length);
            }
            byte[] parambytes = AES.encrypt(bytes, secretKey.getBytes(), algorithm);
            System.out.println("request data size [en] : " + parambytes.length);
            HttpRequestParams<byte[]> params = new HttpRequestParams<byte[]>();
            params.setCharSet("UTF-8");
            params.setMethod("POST");
            params.setHeaders(headers);
            params.setParams(parambytes);
            params.setUrl(url);
            if (url.startsWith("https://")) {
                request = new HttpsRequestBytes(params, null);
            } else {
                request = new HttpRequestBytes(params);
            }
        } catch (Exception e) {
            System.out.println("加密异常");
            e.printStackTrace();
        }
        HttpClient client = new HttpClient();
        String code = null;
        String result = null;
        try {
            HttpResponseBytes res = client.service(request, new HttpResponseBytesPraser());
            if (res == null) {
                System.out.println("请求接口异常");
                return new ResultModel(code, result);
            }
            if (res.getResultCode().equals(HttpResultCode.SUCCESS)) {
                if (res.getHttpCode() == 200) {
                    code = res.getHeaders().get("result");
                    if (code.equals("SUCCESS")) {
                        byte[] data = res.getResult();
                        System.out.println("response data size [en and com] : " + data.length);
                        data = AES.decrypt(data, secretKey.getBytes(), algorithm);
                        if (isGzip) {
                            data = GZIPUtils.decompress(data);
                        }
                        System.out.println("response data size : " + data.length);
                        result = new String(data, encode);
                        System.out.println("response json: " + result);
                    }
                } else {
                    System.out.println("请求接口异常,请求码:" + res.getHttpCode());
                }
            } else {
                System.out.println("请求接口网络异常:" + res.getResultCode().getCode());
            }
        } catch (Exception e) {
            System.out.println("解析失败");
            e.printStackTrace();
        }
        ResultModel re = new ResultModel(code, result);
        return re;
    }

    /**
     * 验证验证码
     * @param smsBO
     * @return
     */
    public Map<String, Object> verifyCode(SmsBO smsBO) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", smsBO.getMobile());
        paramMap.put("client_id", smsBO.getClientId());
        paramMap.put("app_version", smsBO.getAppVersion());
        paramMap.put("app_key", smsBO.getAppKey());
        if(smsBO.getCodeType() != null){
            paramMap.put("code_type", String.valueOf(smsBO.getCodeType()));
        }
        paramMap.put("verifyCode", smsBO.getVerifyCode());
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/sms/verifyCode");
    }

    /**
     * 验证用户是否存在
     * @param loginBO
     * @return
     */
    public Map<String, Object> verUrl(LoginBO loginBO) {
        Map<String, String> paramMap = new HashMap<String, String>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        paramMap.put("timestamp", timestamp);
        paramMap.put("phone", loginBO.getMobile());
        paramMap.put("client_id", loginBO.getClientId());
        paramMap.put("app_version", loginBO.getAppVersion());
        paramMap.put("app_key", loginBO.getAppKey());
        return doPost(paramMap, ymlConfig.getUserCenterUrl() + "/reg/verifyMobie");
    }


    /**
     * 发送post请求
     * @param paramMap
     * @param url
     * @return
     */
    private Map<String, Object> doPost(Map<String, String> paramMap, String url) {

        String resultJsong = HttpUtils.doPost(url, paramMap);
        log.info("--------------->resultJsong:"+resultJsong);
        JSONObject jasonObject = JSONObject.parseObject(resultJsong);
        Map<String, Object> map1 = (Map) jasonObject;
        return map1;
    }

    public static void main(String[] args){
        setSingleSms("EUCP-EMY-SMS1-2NNJY","18D23AB09D42BCBD","http://shmtn.b2m.cn","AES/ECB/PKCS5Padding","您的短信验证码是123456","","","13568857782",false,"UTF-8");
    }
    // 获取6位随机验证码
    public static String getRandom() {
        String num = "";
        for (int i = 0 ; i < 6 ; i ++) {
            num = num + String.valueOf((int) Math.floor(Math.random() * 9 + 1));
        }
        return num;
    }
}
